image.png

Array vs List¶

image.png

In [2]:
lst = [1, 2.5, "hi", [1,2,3], True]
lst
Out[2]:
[1, 2.5, 'hi', [1, 2, 3], True]
In [9]:
id(lst)
Out[9]:
2056599975552
In [10]:
x = 5
id(x)
Out[10]:
140733608203176
In [11]:
y = 5
id(y)
Out[11]:
140733608203176
In [ ]:
# !pip install numpy
In [5]:
import numpy as np
In [12]:
lst = [1, 2, 3, 4, 5]

arr = np.array(lst)
arr
Out[12]:
array([1, 2, 3, 4, 5])
In [13]:
arr.dtype
Out[13]:
dtype('int32')
In [16]:
arr = arr.astype('float32')
arr
Out[16]:
array([1., 2., 3., 4., 5.], dtype=float32)
In [15]:
arr
Out[15]:
array([1, 2, 3, 4, 5])
In [ ]:
np.array(lst)
In [18]:
arr = np.array(lst, dtype='float32')
arr
Out[18]:
array([1., 2., 3., 4., 5.], dtype=float32)
In [19]:
for i in lst:
    print(i)
1
2
3
4
5
In [20]:
for i in arr:
    print(i)
1.0
2.0
3.0
4.0
5.0

image.png

In [31]:
arr = np.array([1,2,3,4,5])
arr
Out[31]:
array([1, 2, 3, 4, 5])
In [32]:
arr.ndim
Out[32]:
1
In [33]:
arr.shape
Out[33]:
(5,)
In [35]:
arr = np.array([[1],[2],[3],[4],[5]])
arr.shape
Out[35]:
(5, 1)
In [25]:
arr = np.array([
    [1, 2, 3],
    [1, 2, 3],
    [1, 2, 3],
    [1, 2, 3],
    [1, 2, 3],
    [1, 2, 3],
])
arr.shape
Out[25]:
(6, 3)

image.png

In [36]:
lst = [7, 2, 9, 10, 11]
arr = np.array(lst)

print(arr.shape)
arr
(5,)
Out[36]:
array([ 7,  2,  9, 10, 11])
In [37]:
lst = [[7, 2, 9, 10, 11]]
arr = np.array(lst)

print(arr.shape)
arr
(1, 5)
Out[37]:
array([[ 7,  2,  9, 10, 11]])
In [39]:
lst = [[[5, 3, 4], [9, 1, 3]], [[5, 3, 4], [9, 1, 3]], [[5, 3, 4], [9, 1, 3]]]
arr = np.array(lst)

print(arr.shape)
arr
(3, 2, 3)
Out[39]:
array([[[5, 3, 4],
        [9, 1, 3]],

       [[5, 3, 4],
        [9, 1, 3]],

       [[5, 3, 4],
        [9, 1, 3]]])

Append Item¶

In [40]:
lst = [1, 2, 3, 4, 5]
lst
Out[40]:
[1, 2, 3, 4, 5]
In [41]:
lst.append(6)
lst
Out[41]:
[1, 2, 3, 4, 5, 6]
In [45]:
arr = np.array([1, 2, 3, 4, 5])
arr
Out[45]:
array([1, 2, 3, 4, 5])
In [46]:
np.append(arr, [6])
Out[46]:
array([1, 2, 3, 4, 5, 6])
In [57]:
arr2 = np.arange(0, 9)
arr2 = arr2.reshape((3,3))
arr2
Out[57]:
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])
In [58]:
np.append(arr2, [6])    # It flattens then append
Out[58]:
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 6])
In [47]:
np.max(arr)
Out[47]:
5
In [48]:
arr.max()
Out[48]:
5
In [63]:
lst1 = [1, 2, 3]
lst2 = [4, 5, 6]

lst1.extend(lst2)
lst1
Out[63]:
[1, 2, 3, 4, 5, 6]
In [64]:
lst1 = [1, 2, 3]
lst2 = [4, 5, 6]

lst1 + lst2
Out[64]:
[1, 2, 3, 4, 5, 6]
In [65]:
arr1 = np.array([1, 2, 3])
arr2 = np.array([4, 5, 6])

arr1 + arr2
Out[65]:
array([5, 7, 9])

Reshape¶

In [67]:
# np.array(range(6))
Out[67]:
array([0, 1, 2, 3, 4, 5])
In [68]:
arr = np.arange(6)
print(arr)
arr.shape
[0 1 2 3 4 5]
Out[68]:
(6,)
In [70]:
arr.reshape((2, 3))
Out[70]:
array([[0, 1, 2],
       [3, 4, 5]])
In [71]:
arr.reshape((3, 2))
Out[71]:
array([[0, 1],
       [2, 3],
       [4, 5]])
In [72]:
arr.reshape((4, 1))
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[72], line 1
----> 1 arr.reshape((4, 1))

ValueError: cannot reshape array of size 6 into shape (4,1)
In [73]:
arr.reshape((6, 1))
Out[73]:
array([[0],
       [1],
       [2],
       [3],
       [4],
       [5]])
In [74]:
arr.reshape((6))
Out[74]:
array([0, 1, 2, 3, 4, 5])
In [80]:
arr #.shape
Out[80]:
array([0, 1, 2, 3, 4, 5])
In [ ]:
 
In [83]:
arr.reshape((3, -1))
Out[83]:
array([[0, 1],
       [2, 3],
       [4, 5]])
In [86]:
arr.reshape((-1))
Out[86]:
array([0, 1, 2, 3, 4, 5])
In [76]:
arr.reshape((3, -1))  # 3, 2
Out[76]:
array([[0, 1],
       [2, 3],
       [4, 5]])
In [77]:
arr.reshape((6, -1))  # 6, 1
Out[77]:
array([[0],
       [1],
       [2],
       [3],
       [4],
       [5]])
In [78]:
arr.reshape((-1))  # 6, 1
Out[78]:
array([0, 1, 2, 3, 4, 5])

Mathematical Operations¶

In [93]:
lst1 = [1, 2, 3, 4, 5]
arr1 = np.array(lst1)
arr1
Out[93]:
array([1, 2, 3, 4, 5])
In [94]:
lst2 = [10, 20, 30, 40, 50]
arr2 = np.array(lst2)
arr2
Out[94]:
array([10, 20, 30, 40, 50])
In [95]:
arr1 + arr2
Out[95]:
array([11, 22, 33, 44, 55])
In [96]:
arr1 * arr2
Out[96]:
array([ 10,  40,  90, 160, 250])
In [98]:
arr1 * 10
Out[98]:
array([10, 20, 30, 40, 50])
In [99]:
arr1 / 10
Out[99]:
array([0.1, 0.2, 0.3, 0.4, 0.5])
In [100]:
arr1**2
Out[100]:
array([ 1,  4,  9, 16, 25])
In [101]:
np.power(arr1, 2)
Out[101]:
array([ 1,  4,  9, 16, 25], dtype=int32)
In [102]:
np.sqrt(arr1)
Out[102]:
array([1.        , 1.41421356, 1.73205081, 2.        , 2.23606798])
In [103]:
arr1**0.5
Out[103]:
array([1.        , 1.41421356, 1.73205081, 2.        , 2.23606798])
In [104]:
np.rad2deg(3.14)
Out[104]:
179.9087476710785
In [105]:
np.pi
Out[105]:
3.141592653589793
In [106]:
np.rad2deg(np.pi)
Out[106]:
180.0

Attributes of NumPy Arrays¶

In [121]:
arr = np.arange(24).reshape(2, -1, 4)
arr
Out[121]:
array([[[ 0,  1,  2,  3],
        [ 4,  5,  6,  7],
        [ 8,  9, 10, 11]],

       [[12, 13, 14, 15],
        [16, 17, 18, 19],
        [20, 21, 22, 23]]])
In [122]:
arr.shape
Out[122]:
(2, 3, 4)
In [123]:
len(arr.shape)
Out[123]:
3
In [124]:
arr.size
Out[124]:
24
In [125]:
arr.dtype
Out[125]:
dtype('int32')
In [126]:
arr.astype('float')
Out[126]:
array([[[ 0.,  1.,  2.,  3.],
        [ 4.,  5.,  6.,  7.],
        [ 8.,  9., 10., 11.]],

       [[12., 13., 14., 15.],
        [16., 17., 18., 19.],
        [20., 21., 22., 23.]]])

image.png

In [129]:
arr = np.arange(24).reshape(3, 8)
arr
Out[129]:
array([[ 0,  1,  2,  3,  4,  5,  6,  7],
       [ 8,  9, 10, 11, 12, 13, 14, 15],
       [16, 17, 18, 19, 20, 21, 22, 23]])
In [135]:
arr.reshape(-1)
Out[135]:
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
       17, 18, 19, 20, 21, 22, 23])
In [136]:
arr.ravel()
Out[136]:
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
       17, 18, 19, 20, 21, 22, 23])
In [137]:
arr.flatten()
Out[137]:
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
       17, 18, 19, 20, 21, 22, 23])
In [139]:
arr
Out[139]:
array([[ 0,  1,  2,  3,  4,  5,  6,  7],
       [ 8,  9, 10, 11, 12, 13, 14, 15],
       [16, 17, 18, 19, 20, 21, 22, 23]])
In [142]:
arr3 = arr.reshape((1, 3, 1, 8, 1, 1))
arr3
Out[142]:
array([[[[[[ 0]],

          [[ 1]],

          [[ 2]],

          [[ 3]],

          [[ 4]],

          [[ 5]],

          [[ 6]],

          [[ 7]]]],



        [[[[ 8]],

          [[ 9]],

          [[10]],

          [[11]],

          [[12]],

          [[13]],

          [[14]],

          [[15]]]],



        [[[[16]],

          [[17]],

          [[18]],

          [[19]],

          [[20]],

          [[21]],

          [[22]],

          [[23]]]]]])
In [145]:
arr3.ravel()
Out[145]:
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
       17, 18, 19, 20, 21, 22, 23])
In [146]:
arr3.reshape(-1)
Out[146]:
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
       17, 18, 19, 20, 21, 22, 23])

image.png

In [185]:
img = np.zeros((256, 256, 3))
img[:128, :128, 0]  = 1.0
# img[128:, 128:, 1]  = 1.0
In [186]:
import matplotlib.pyplot as plt

plt.imshow(img);
In [187]:
img.shape
Out[187]:
(256, 256, 3)
In [189]:
img = np.zeros((64, 256, 256, 3))
img.shape
Out[189]:
(64, 256, 256, 3)
In [ ]:
6400
In [190]:
img = np.zeros((256, 256, 3))
img.shape
Out[190]:
(256, 256, 3)
In [192]:
img.reshape((1, 256, 256, 3)).shape
Out[192]:
(1, 256, 256, 3)
In [195]:
np.expand_dims(img, axis=0).shape
Out[195]:
(1, 256, 256, 3)
In [203]:
img = np.expand_dims(img, axis=0)
img.shape
Out[203]:
(1, 256, 256, 3)
In [205]:
img.reshape((1, -1)).shape
Out[205]:
(1, 196608)
In [332]:
img = np.random.random((256, 256, 3))
plt.imshow(img);

Generating Data¶

In [200]:
np.arange(24).reshape(4, 6)
Out[200]:
array([[ 0,  1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10, 11],
       [12, 13, 14, 15, 16, 17],
       [18, 19, 20, 21, 22, 23]])
In [206]:
arr_zeros = np.zeros((3, 4))
arr_zeros
Out[206]:
array([[0., 0., 0., 0.],
       [0., 0., 0., 0.],
       [0., 0., 0., 0.]])
In [207]:
np.ones((3,4))
Out[207]:
array([[1., 1., 1., 1.],
       [1., 1., 1., 1.],
       [1., 1., 1., 1.]])
In [209]:
arr = np.ones([3, 4]) * 50
arr
Out[209]:
array([[50., 50., 50., 50.],
       [50., 50., 50., 50.],
       [50., 50., 50., 50.]])
In [210]:
arr.shape
Out[210]:
(3, 4)
In [213]:
arr2 = np.zeros(arr.shape)
arr2
Out[213]:
array([[0., 0., 0., 0.],
       [0., 0., 0., 0.],
       [0., 0., 0., 0.]])
In [214]:
arr2 = np.zeros_like(arr)
arr2
Out[214]:
array([[0., 0., 0., 0.],
       [0., 0., 0., 0.],
       [0., 0., 0., 0.]])
In [215]:
np.ones_like(arr_zeros)
Out[215]:
array([[1., 1., 1., 1.],
       [1., 1., 1., 1.],
       [1., 1., 1., 1.]])
In [220]:
np.eye(5)
Out[220]:
array([[1., 0., 0., 0., 0.],
       [0., 1., 0., 0., 0.],
       [0., 0., 1., 0., 0.],
       [0., 0., 0., 1., 0.],
       [0., 0., 0., 0., 1.]])

Linspace¶

np.linspace(0, 100, 4)

In [221]:
np.linspace(0, 1, 11)
Out[221]:
array([0. , 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1. ])
In [225]:
np.arange(0, 1.0000001, 0.1)
Out[225]:
array([0. , 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1. ])

Random¶

In [336]:
# Return random floats in the half-open interval [0.0, 1.0)
np.random.random()
Out[336]:
0.7039177137285235
In [262]:
np.random.random((3,4))
Out[262]:
array([[0.16910139, 0.79887745, 0.67021357, 0.70816144],
       [0.61535757, 0.18376302, 0.40791498, 0.18348666],
       [0.32516788, 0.35982663, 0.82460407, 0.00337169]])
In [326]:
np.random.rand(3, 4)
Out[326]:
array([[0.27235092, 0.42353828, 0.68604708, 0.61573022],
       [0.20079542, 0.12818271, 0.08706981, 0.49023664],
       [0.62600469, 0.57818759, 0.27746641, 0.17027698]])
In [324]:
# from `low` (inclusive) to `high` (exclusive).
np.random.randint(0, 10, size=(2, 3))
Out[324]:
array([[5, 2, 5],
       [1, 9, 8]])
In [337]:
# Return a sample (or samples) from the "standard normal" distribution.
np.random.randn(3)
Out[337]:
array([-1.59977171,  1.40310673,  0.36754629])

Statistics operations¶

In [378]:
np.random.seed(5)

np.random.rand()
Out[378]:
0.22199317108973948
In [391]:
arr = np.random.random((10, 3)) * 10
arr
Out[391]:
array([[3.48331994e+00, 5.91222311e+00, 7.75013130e+00],
       [6.24754467e+00, 1.59680933e+00, 8.93762653e+00],
       [7.30591266e+00, 4.97768019e+00, 6.43640219e+00],
       [5.09475094e+00, 1.68208158e+00, 6.41464773e+00],
       [9.88167763e+00, 7.70329363e+00, 1.81481209e+00],
       [1.19769021e+00, 9.30341843e+00, 9.10097433e+00],
       [7.49184660e+00, 7.60531540e+00, 1.42875798e+00],
       [8.11944192e+00, 1.92279296e+00, 1.54745110e+00],
       [4.07078957e+00, 3.82894367e-03, 8.45517816e+00],
       [1.61132453e+00, 7.39250735e+00, 5.82910816e+00]])
In [387]:
arr.mean()
Out[387]:
5.621313595430986
In [388]:
arr.mean(axis=0)
Out[388]:
array([5.54498867, 5.19038766, 6.12856445])
In [389]:
arr.mean(axis=1)
Out[389]:
array([6.1282999 , 8.23874849, 3.87078739, 3.08419968, 6.00425269,
       5.03635079, 7.59133363, 4.3727355 , 8.32647883, 3.55994906])
In [393]:
arr.std(axis=1)
Out[393]:
array([1.74747934, 3.03229793, 0.96058921, 1.99403616, 3.40740845,
       3.7742654 , 2.88528413, 3.01349563, 3.45105999, 2.44167498])
In [394]:
arr.std(axis=0)
Out[394]:
array([2.71531091, 3.09567141, 2.92306853])
In [396]:
arr.std(axis=0) ** 2
Out[396]:
array([7.37291334, 9.58318147, 8.54432961])
In [395]:
arr.var(axis=0)
Out[395]:
array([7.37291334, 9.58318147, 8.54432961])
In [401]:
arr.max(axis=0)
Out[401]:
array([9.88167763, 9.30341843, 9.10097433])
In [403]:
arr.argmax(axis=0)
Out[403]:
array([4, 5, 5], dtype=int64)

Indexing and Slicing¶

In [404]:
arr = np.arange(12).reshape(3, 4)
arr
Out[404]:
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
In [407]:
arr[0][0]
Out[407]:
0
In [408]:
arr[0, 0]
Out[408]:
0
In [409]:
arr[1, 1]
Out[409]:
5
In [410]:
arr[2, 3]
Out[410]:
11
In [411]:
arr[(1,2), (1,3)]
Out[411]:
array([ 5, 11])
In [414]:
arr[(1,2), (1,3)] = 1000
arr
Out[414]:
array([[   0,    1,    2,    3],
       [   4, 1000,    6,    7],
       [   8,    9,   10, 1000]])
In [415]:
arr
Out[415]:
array([[   0,    1,    2,    3],
       [   4, 1000,    6,    7],
       [   8,    9,   10, 1000]])
In [417]:
arr[:, :]
Out[417]:
array([[   0,    1,    2,    3],
       [   4, 1000,    6,    7],
       [   8,    9,   10, 1000]])
In [418]:
arr[0]
Out[418]:
array([0, 1, 2, 3])
In [419]:
arr[0, :]
Out[419]:
array([0, 1, 2, 3])
In [424]:
arr[:2, :2]
Out[424]:
array([[   0,    1],
       [   4, 1000]])
In [427]:
arr[1:3, 1:3]
Out[427]:
array([[1000,    6],
       [   9,   10]])

image.png

In [429]:
arr[1]
Out[429]:
array([   4, 1000,    6,    7])
In [436]:
arr[::]
Out[436]:
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12])
In [437]:
arr
Out[437]:
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12])
In [440]:
arr[::2]
Out[440]:
array([ 0,  2,  4,  6,  8, 10, 12])
In [439]:
arr[1::2]
Out[439]:
array([ 1,  3,  5,  7,  9, 11])
In [441]:
arr[::-1]
Out[441]:
array([12, 11, 10,  9,  8,  7,  6,  5,  4,  3,  2,  1,  0])
In [442]:
arr[::-2]
Out[442]:
array([12, 10,  8,  6,  4,  2,  0])

Boolean Mask Arrays¶

In [445]:
arr = np.random.randint(0, 15, size=12)
arr
Out[445]:
array([ 2,  7, 12, 13,  6, 13,  5, 14, 10, 14,  2,  6])
In [446]:
bool_list = []
for i in arr:
    if i % 2 == 0:
        bool_list.append(i)

bool_list
Out[446]:
[2, 12, 6, 14, 10, 14, 2, 6]
In [447]:
arr%2
Out[447]:
array([0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0], dtype=int32)
In [449]:
mask = arr%2 == 0
mask
Out[449]:
array([ True, False,  True, False,  True, False, False,  True,  True,
        True,  True,  True])
In [451]:
arr
Out[451]:
array([ 2,  7, 12, 13,  6, 13,  5, 14, 10, 14,  2,  6])
In [450]:
arr[mask]
Out[450]:
array([ 2, 12,  6, 14, 10, 14,  2,  6])
In [453]:
mask.astype(int)
Out[453]:
array([1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1])
In [454]:
mask.sum()
Out[454]:
8
In [455]:
len(arr[mask])
Out[455]:
8
In [456]:
mask.dtype
Out[456]:
dtype('bool')
In [457]:
arr + 5
Out[457]:
array([ 7, 12, 17, 18, 11, 18, 10, 19, 15, 19,  7, 11])

Matrix Operations¶

elementwise operations¶

In [458]:
mat_1 = np.array(range(10, 14))
mat_1 = np.reshape(mat_1, (2, 2))
mat_1
Out[458]:
array([[10, 11],
       [12, 13]])
In [460]:
mat_1 = np.array([[10, 11],
                  [12, 13]])
mat_1
Out[460]:
array([[10, 11],
       [12, 13]])
In [461]:
mat_2 = np.array([[30, 31],
                  [32, 33]])
mat_2
Out[461]:
array([[30, 31],
       [32, 33]])
In [462]:
mat_1 + mat_2
Out[462]:
array([[40, 42],
       [44, 46]])
In [463]:
mat_1 - mat_2
Out[463]:
array([[-20, -20],
       [-20, -20]])
In [464]:
mat_1 * mat_2
Out[464]:
array([[300, 341],
       [384, 429]])
In [465]:
mat_1 / mat_2
Out[465]:
array([[0.33333333, 0.35483871],
       [0.375     , 0.39393939]])
In [466]:
mat_1 % mat_2
Out[466]:
array([[10, 11],
       [12, 13]])

scaler operations¶

In [467]:
5 * mat_1
Out[467]:
array([[50, 55],
       [60, 65]])
In [470]:
mat_1 = np.array([[2, 4], [7, 8], [3, 2]])
mat_1 # 3 x 2
Out[470]:
array([[2, 4],
       [7, 8],
       [3, 2]])
In [471]:
mat_2 = np.array([[1, 3], [4, 7]])
mat_2 # 2 x 2
Out[471]:
array([[1, 3],
       [4, 7]])

dot product¶

In [475]:
np.dot(mat_1, mat_2)
Out[475]:
array([[18, 34],
       [39, 77],
       [11, 23]])
In [476]:
mat_1.dot(mat_2)
Out[476]:
array([[18, 34],
       [39, 77],
       [11, 23]])
In [477]:
mat_1 @ mat_2
Out[477]:
array([[18, 34],
       [39, 77],
       [11, 23]])
In [478]:
np.matmul(mat_1, mat_2)
Out[478]:
array([[18, 34],
       [39, 77],
       [11, 23]])
In [474]:
# np.max(arr)
# arr.max()

matrix transpose¶

In [479]:
mat_1.T
Out[479]:
array([[2, 7, 3],
       [4, 8, 2]])
In [480]:
np.transpose(mat_1)
Out[480]:
array([[2, 7, 3],
       [4, 8, 2]])
In [481]:
mat_1.transpose()
Out[481]:
array([[2, 7, 3],
       [4, 8, 2]])

Meshgrid¶

x = np.linspace(-3, 3, 5)
    y = np.linspace(-3, 3, 5)

    xx, yy = np.meshgrid(x, y)

    plt.scatter(xx, yy)

In [482]:
x = np.linspace(-3, 3, 5)
y = np.linspace(-3, 3, 5)

print(x)
print(y)
[-3.  -1.5  0.   1.5  3. ]
[-3.  -1.5  0.   1.5  3. ]
In [485]:
import matplotlib.pyplot as plt 

plt.scatter(x, y);
In [486]:
xx, yy = np.meshgrid(x, y)
In [487]:
print(xx)
[[-3.  -1.5  0.   1.5  3. ]
 [-3.  -1.5  0.   1.5  3. ]
 [-3.  -1.5  0.   1.5  3. ]
 [-3.  -1.5  0.   1.5  3. ]
 [-3.  -1.5  0.   1.5  3. ]]
In [488]:
print(yy)
[[-3.  -3.  -3.  -3.  -3. ]
 [-1.5 -1.5 -1.5 -1.5 -1.5]
 [ 0.   0.   0.   0.   0. ]
 [ 1.5  1.5  1.5  1.5  1.5]
 [ 3.   3.   3.   3.   3. ]]
In [489]:
plt.scatter(xx, yy);
In [ ]:
 
In [597]:
import numpy as np
import matplotlib.pyplot as plt

# Generate x and y values using np.linspace
x = np.linspace(-3, 3, 5) # (5,)
y = np.linspace(-3, 3, 5) # (5,)

# Expand dimensions of x and y
x_expanded = np.expand_dims(x, axis=1)  # Expands x to shape (5, 1)
y_expanded = np.expand_dims(y, axis=0)  # Expands y to shape (1, 5)

# Now, x_expanded and y_expanded are 2D arrays that can be broadcasted
X, Y = x_expanded, y_expanded

# # Flatten the 2D arrays for scatter plotting
# X = X.ravel()
# Y = Y.ravel()

# Scatter plot
plt.scatter(X, Y)
Out[597]:
<matplotlib.collections.PathCollection at 0x1de80a16c50>

Stacking¶

In [492]:
arr_1 = np.array([[0, 2], [7, 6]])
arr_2 = np.array([[3, 7], [1, 4]])

np.vstack([arr_1, arr_2])
Out[492]:
array([[0, 2],
       [7, 6],
       [3, 7],
       [1, 4]])
In [493]:
np.hstack([arr_1, arr_2])
Out[493]:
array([[0, 2, 3, 7],
       [7, 6, 1, 4]])

Depth stacking

img = np.dstack([arr1, arr2, arr3])

image.png

In [503]:
a = np.array([1, 2])
b = np.array([3, 4])

np.dot(a, b)
Out[503]:
11
In [496]:
a @ b
Out[496]:
11
In [497]:
np.sum(a * b)
Out[497]:
11
In [498]:
result = 0
for i in range(len(a)):
    result += a[i] * b[i]

result
Out[498]:
11
In [505]:
a = np.array([[1, 2]])
b = np.array([[3, 4]])

print(a.shape)
print(b.shape)
(1, 2)
(1, 2)
In [506]:
np.dot(a, b)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[506], line 1
----> 1 np.dot(a, b)

File <__array_function__ internals>:200, in dot(*args, **kwargs)

ValueError: shapes (1,2) and (1,2) not aligned: 2 (dim 1) != 1 (dim 0)
In [507]:
a @ b.T
Out[507]:
array([[11]])
In [509]:
a
Out[509]:
array([[1, 2]])
In [508]:
b.T
Out[508]:
array([[3],
       [4]])
In [511]:
# Magnitude
a = np.array([3, 4])
np.linalg.norm(a)
Out[511]:
5.0

Speed Test¶

In [517]:
import time
t1 = time.time()
for i in range(1000_000):
    x= 5+5
t2 = time.time()

t2 - t1
Out[517]:
0.05953621864318848
In [523]:
%%time

for i in range(1000_000):
    x= 5+5
CPU times: total: 78.1 ms
Wall time: 70.1 ms
In [524]:
%%timeit

for i in range(1000_000):
    x= 5+5
24.3 ms ± 475 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
In [534]:
def slow_dot_product(a, b):
    result = 0
    for i in range(len(a)):
        result += a[i] * b[i]
    return result


a = np.random.randn(1000_000)
b = np.random.randn(1000_000)
slow_dot_product(a, b)
Out[534]:
1220.0138861196572
In [530]:
# number of experiments 
T = 1000

a = np.random.randn(10_000)
b = np.random.randn(10_000)
In [531]:
tic = time.process_time()

for t in range(T):
    slow_dot_product(a, b)
    
toc = time.process_time()
dt1 = toc - tic

print("Time in sec:", dt1)
Time in sec: 2.75
In [532]:
tic = time.process_time()

for t in range(T):
    a @ b
    
toc = time.process_time()
dt1 = toc - tic

print("Time in sec:", dt1)
Time in sec: 0.015625
In [533]:
2.75 / 0.015625
Out[533]:
176.0

image.png

In [538]:
arr = np.array([[1, 2], [3, 4]])
arr
Out[538]:
array([[1, 2],
       [3, 4]])
In [539]:
np.linalg.det(arr)
Out[539]:
-2.0000000000000004
In [540]:
np.trace(arr)
Out[540]:
5

image.png

In [541]:
np.linalg.eig(arr)
Out[541]:
(array([-0.37228132,  5.37228132]),
 array([[-0.82456484, -0.41597356],
        [ 0.56576746, -0.90937671]]))

image.png

image.png

In [542]:
A = np.array([[1, 1], [1.5, 4]])
b = np.array([2200, 5050])
In [543]:
A_inv = np.linalg.inv(A)
A_inv.dot(b)
Out[543]:
array([1500.,  700.])
In [544]:
np.linalg.solve(A, b)
Out[544]:
array([1500.,  700.])

image.png

image.png

In [549]:
data = np.random.rand(3, 5)
np.corrcoef(data.T)
Out[549]:
array([[ 1.        ,  0.16327515,  0.99999866,  0.90101648,  0.90102699],
       [ 0.16327515,  1.        ,  0.16489153, -0.28085011,  0.5750575 ],
       [ 0.99999866,  0.16489153,  1.        ,  0.90030448,  0.90173654],
       [ 0.90101648, -0.28085011,  0.90030448,  1.        ,  0.62368033],
       [ 0.90102699,  0.5750575 ,  0.90173654,  0.62368033,  1.        ]])

View vs deep-Copy¶

In [550]:
arr1 = np.random.randn(2, 3)
arr2 = arr1


# Referenece Equality
print(id(arr1))
print(id(arr2))

arr2 is arr1
2057035845520
2057035845520
Out[550]:
True
In [551]:
arr1
Out[551]:
array([[-0.14389912, -0.26846048, -0.52502538],
       [ 0.91390907,  0.26495336,  1.46164214]])
In [553]:
arr1[0, 0] = 20000
arr1
Out[553]:
array([[ 2.00000000e+04, -2.68460478e-01, -5.25025381e-01],
       [ 9.13909070e-01,  2.64953357e-01,  1.46164214e+00]])
In [554]:
arr2
Out[554]:
array([[ 2.00000000e+04, -2.68460478e-01, -5.25025381e-01],
       [ 9.13909070e-01,  2.64953357e-01,  1.46164214e+00]])
In [556]:
arr_view = arr1.view().reshape(-1)
arr_view
Out[556]:
array([ 2.00000000e+04, -2.68460478e-01, -5.25025381e-01,  9.13909070e-01,
        2.64953357e-01,  1.46164214e+00])
In [558]:
arr_view[0] = 5555555
In [559]:
arr1
Out[559]:
array([[ 5.55555500e+06, -2.68460478e-01, -5.25025381e-01],
       [ 9.13909070e-01,  2.64953357e-01,  1.46164214e+00]])
In [560]:
arr2
Out[560]:
array([[ 5.55555500e+06, -2.68460478e-01, -5.25025381e-01],
       [ 9.13909070e-01,  2.64953357e-01,  1.46164214e+00]])
In [561]:
arr2 = 5
In [562]:
arr1
Out[562]:
array([[ 5.55555500e+06, -2.68460478e-01, -5.25025381e-01],
       [ 9.13909070e-01,  2.64953357e-01,  1.46164214e+00]])
In [567]:
arr2 = np.array([0,7,8,9,5])
In [568]:
arr1
Out[568]:
array([[ 5.55555500e+06, -2.68460478e-01, -5.25025381e-01],
       [ 9.13909070e-01,  2.64953357e-01,  1.46164214e+00]])

Deep Copy¶

In [569]:
arr_deep = np.copy(arr1)
arr_deep
Out[569]:
array([[ 5.55555500e+06, -2.68460478e-01, -5.25025381e-01],
       [ 9.13909070e-01,  2.64953357e-01,  1.46164214e+00]])
In [570]:
arr_deep[0] = 0
arr_deep
Out[570]:
array([[0.        , 0.        , 0.        ],
       [0.91390907, 0.26495336, 1.46164214]])
In [571]:
arr1
Out[571]:
array([[ 5.55555500e+06, -2.68460478e-01, -5.25025381e-01],
       [ 9.13909070e-01,  2.64953357e-01,  1.46164214e+00]])

Read+Write a simple Dataset.ipynb¶

In [573]:
!cat simple_dataset_to_read.csv
0|1|2|3|4|5|6|7|8|9|10
1|2|3|4|5|6|7|8|9|10|11
2|3|4|5|6|7|8|9|10|11|12
3|4|5|6|7|8|9|10|11|12|13
4|5|6|7|8|9|10|11|12|13|14
5|6|7|8|9|10|11|12|13|14|15
6|7|8|9|10|11|12|13|14|15|16
7|8|9|10|11|12|13|14|15|16|17
8|9|10|11|12|13|14|15|16|17|18
9|10|11|12|13|14|15|16|17|18|19
10|11|12|13|14|15|16|17|18|19|20
In [572]:
arr = np.genfromtxt("simple_dataset_to_read.csv", delimiter='|')
arr 
Out[572]:
array([[ 0.,  1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9., 10.],
       [ 1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9., 10., 11.],
       [ 2.,  3.,  4.,  5.,  6.,  7.,  8.,  9., 10., 11., 12.],
       [ 3.,  4.,  5.,  6.,  7.,  8.,  9., 10., 11., 12., 13.],
       [ 4.,  5.,  6.,  7.,  8.,  9., 10., 11., 12., 13., 14.],
       [ 5.,  6.,  7.,  8.,  9., 10., 11., 12., 13., 14., 15.],
       [ 6.,  7.,  8.,  9., 10., 11., 12., 13., 14., 15., 16.],
       [ 7.,  8.,  9., 10., 11., 12., 13., 14., 15., 16., 17.],
       [ 8.,  9., 10., 11., 12., 13., 14., 15., 16., 17., 18.],
       [ 9., 10., 11., 12., 13., 14., 15., 16., 17., 18., 19.],
       [10., 11., 12., 13., 14., 15., 16., 17., 18., 19., 20.]])
In [574]:
new_arr = arr / 50 
new_arr
Out[574]:
array([[0.  , 0.02, 0.04, 0.06, 0.08, 0.1 , 0.12, 0.14, 0.16, 0.18, 0.2 ],
       [0.02, 0.04, 0.06, 0.08, 0.1 , 0.12, 0.14, 0.16, 0.18, 0.2 , 0.22],
       [0.04, 0.06, 0.08, 0.1 , 0.12, 0.14, 0.16, 0.18, 0.2 , 0.22, 0.24],
       [0.06, 0.08, 0.1 , 0.12, 0.14, 0.16, 0.18, 0.2 , 0.22, 0.24, 0.26],
       [0.08, 0.1 , 0.12, 0.14, 0.16, 0.18, 0.2 , 0.22, 0.24, 0.26, 0.28],
       [0.1 , 0.12, 0.14, 0.16, 0.18, 0.2 , 0.22, 0.24, 0.26, 0.28, 0.3 ],
       [0.12, 0.14, 0.16, 0.18, 0.2 , 0.22, 0.24, 0.26, 0.28, 0.3 , 0.32],
       [0.14, 0.16, 0.18, 0.2 , 0.22, 0.24, 0.26, 0.28, 0.3 , 0.32, 0.34],
       [0.16, 0.18, 0.2 , 0.22, 0.24, 0.26, 0.28, 0.3 , 0.32, 0.34, 0.36],
       [0.18, 0.2 , 0.22, 0.24, 0.26, 0.28, 0.3 , 0.32, 0.34, 0.36, 0.38],
       [0.2 , 0.22, 0.24, 0.26, 0.28, 0.3 , 0.32, 0.34, 0.36, 0.38, 0.4 ]])
In [575]:
np.savetxt('test_save.csv', new_arr, delimiter=',', fmt='%0.2e')
In [576]:
!cat test_save.csv
0.00e+00,2.00e-02,4.00e-02,6.00e-02,8.00e-02,1.00e-01,1.20e-01,1.40e-01,1.60e-01,1.80e-01,2.00e-01
2.00e-02,4.00e-02,6.00e-02,8.00e-02,1.00e-01,1.20e-01,1.40e-01,1.60e-01,1.80e-01,2.00e-01,2.20e-01
4.00e-02,6.00e-02,8.00e-02,1.00e-01,1.20e-01,1.40e-01,1.60e-01,1.80e-01,2.00e-01,2.20e-01,2.40e-01
6.00e-02,8.00e-02,1.00e-01,1.20e-01,1.40e-01,1.60e-01,1.80e-01,2.00e-01,2.20e-01,2.40e-01,2.60e-01
8.00e-02,1.00e-01,1.20e-01,1.40e-01,1.60e-01,1.80e-01,2.00e-01,2.20e-01,2.40e-01,2.60e-01,2.80e-01
1.00e-01,1.20e-01,1.40e-01,1.60e-01,1.80e-01,2.00e-01,2.20e-01,2.40e-01,2.60e-01,2.80e-01,3.00e-01
1.20e-01,1.40e-01,1.60e-01,1.80e-01,2.00e-01,2.20e-01,2.40e-01,2.60e-01,2.80e-01,3.00e-01,3.20e-01
1.40e-01,1.60e-01,1.80e-01,2.00e-01,2.20e-01,2.40e-01,2.60e-01,2.80e-01,3.00e-01,3.20e-01,3.40e-01
1.60e-01,1.80e-01,2.00e-01,2.20e-01,2.40e-01,2.60e-01,2.80e-01,3.00e-01,3.20e-01,3.40e-01,3.60e-01
1.80e-01,2.00e-01,2.20e-01,2.40e-01,2.60e-01,2.80e-01,3.00e-01,3.20e-01,3.40e-01,3.60e-01,3.80e-01
2.00e-01,2.20e-01,2.40e-01,2.60e-01,2.80e-01,3.00e-01,3.20e-01,3.40e-01,3.60e-01,3.80e-01,4.00e-01

Solve Linear Equations in SciPy¶

In [ ]:
# pip install scipy
In [577]:
from scipy import linalg
In [578]:
# Creating input array  
A = np.array([[1, 2, -3], [2, -5, 4], [5, 4, -1]])  
In [579]:
# Solution Array  
b = np.array([[-3], [13], [5]])
In [580]:
# Solve the linear algebra  
x = linalg.solve(A, b) 
x 
Out[580]:
array([[ 2.],
       [-1.],
       [ 1.]])
In [582]:
np.linalg.norm(A.dot(x) - b )
Out[582]:
4.440892098500626e-16

Broadcasting¶

  • Two dimensions NOT equal to each other and not any of them equal ONE --> Error raised
  • Broadcasting is simply a set of rules for applying binary ufuncs (e.g., addition, subtraction, multiplication, etc.) on arrays of different sizes.
Check Dimensions --> (5,) + (2, 5) --> should be the same¶

(1, 5) + (2, 5)

In [586]:
a = np.array([1, 2, 3, 4, 5])                      # (5,)
b = np.array([[0, 0, 0, 0, 0], [5, 5, 5, 5, 5]])   # (2, 5)

print(a.shape)
print(b.shape)

a + b
(5,)
(2, 5)
Out[586]:
array([[ 1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10]])
In [585]:
z = a + b
z.shape
Out[585]:
(2, 5)
In [587]:
a = np.array([[1, 2, 3, 4, 5]])                    # (1, 5)
b = np.array([[0, 0, 0, 0, 0], [5, 5, 5, 5, 5]])   # (2, 5)

print(a.shape)
print(b.shape)

a + b
(1, 5)
(2, 5)
Out[587]:
array([[ 1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10]])
In [588]:
a = np.array([[1, 2, 3, 4, 5], [1, 2, 3, 4, 5]])   # (2, 5)
b = np.array([[0, 0, 0, 0, 0], [5, 5, 5, 5, 5]])   # (2, 5)

print(a.shape)
print(b.shape)

a + b
(2, 5)
(2, 5)
Out[588]:
array([[ 1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10]])
In [ ]:
 
In [589]:
a = np.array([1, 2, 3, 4, 5])                            # (5,)
b = np.array([[0, 5], [0, 5], [0, 5], [0, 5], [0, 5]])   # (5, 2)

print(a.shape)
print(b.shape)

a + b
(5,)
(5, 2)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[589], line 7
      4 print(a.shape)
      5 print(b.shape)
----> 7 a + b

ValueError: operands could not be broadcast together with shapes (5,) (5,2) 
In [591]:
a = np.array([[1, 2, 3, 4, 5]])                          # (1, 5)
b = np.array([[0, 5], [0, 5], [0, 5], [0, 5], [0, 5]])   # (5, 2)

print(a.shape)
print(b.shape)

a + b
(1, 5)
(5, 2)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[591], line 7
      4 print(a.shape)
      5 print(b.shape)
----> 7 a + b

ValueError: operands could not be broadcast together with shapes (1,5) (5,2) 
In [592]:
a = np.array([[1, 2, 3, 4, 5]])                    # (1, 5)
b = np.array([[0, 0, 0, 0, 0], [5, 5, 5, 5, 5]])   # (2, 5)

print(a.shape)
print(b.shape)

a + b
(1, 5)
(2, 5)
Out[592]:
array([[ 1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10]])
In [593]:
a = np.array([[1], [2], [3], [4], [5]])   # (5, 5)
b = np.array([[5, 5, 5, 5, 5]])           # (5, 5)

print(a.shape)
print(b.shape)

a + b
(5, 1)
(1, 5)
Out[593]:
array([[ 6,  6,  6,  6,  6],
       [ 7,  7,  7,  7,  7],
       [ 8,  8,  8,  8,  8],
       [ 9,  9,  9,  9,  9],
       [10, 10, 10, 10, 10]])

Lab Assignment¶

Q1:¶

image.png

In [ ]:
 
In [ ]:
 

image.png

In [ ]:
 
In [ ]:
 
In [ ]:
 

Q3: Implement the L1 and L2 loss functions¶

Exercise: Implement the numpy vectorized version of the L1 loss. You may find the function abs(x) (absolute value of x) useful.

Reminder:

  • The loss is used to evaluate the performance of your model. The bigger your loss is, the more different your predictions ($ \hat{y} $) are from the true values ($y$). In deep learning, you use optimization algorithms like Gradient Descent to train your model and to minimize the cost.
  • L1 loss is defined as: $$\begin{align*} & L_1(\hat{y}, y) = \sum_{i=0}^m|y^{(i)} - \hat{y}^{(i)}| \end{align*}\tag{6}$$

Expected Output:

L1 1.1
In [ ]:
def L1(yhat, y):
    """
    Arguments:
    yhat -- vector of size m (predicted labels)
    y -- vector of size m (true labels)
    
    Returns:
    loss -- the value of the L1 loss function defined above
    """
    
    ### START CODE HERE ### (≈ 1 line of code)
    loss = None
    ### END CODE HERE ###
    
    return loss
In [ ]:
yhat = np.array([.9, 0.2, 0.1, .4, .9])
y    = np.array([1 ,  0 ,  0 ,  1, 1])

l1_loss = L1(yhat,y)
print("L1 = " + str(l1_loss))
In [ ]:
 
In [ ]:
 

Exercise: Implement the numpy vectorized version of the L2 loss. There are several way of implementing the L2 loss but you may find the function np.dot() useful. As a reminder, if $x = [x_1, x_2, ..., x_n]$, then np.dot(x,x) = $\sum_{j=0}^n x_j^{2}$.

  • L2 loss is defined as $$\begin{align*} & L_2(\hat{y},y) = \sum_{i=0}^m(y^{(i)} - \hat{y}^{(i)})^2 \end{align*}\tag{7}$$

Expected Output:

L2 0.43
In [ ]:
def L2(yhat, y):
    """
    Arguments:
    yhat -- vector of size m (predicted labels)
    y -- vector of size m (true labels)
    
    Returns:
    loss -- the value of the L2 loss function defined above
    """
    
    ### START CODE HERE ### (≈ 1 line of code)
    loss = None
    ### END CODE HERE ###
    
    return loss
In [ ]:
yhat = np.array([.9, 0.2, 0.1, .4, .9])
y    = np.array([1 ,  0 ,  0 ,  1, 1])

l2_loss = L2(yhat,y)

print("L2 = " + str(l2_loss))
In [ ]:
 
In [ ]:
 

image.png

In [ ]:
 
In [ ]:
 
In [ ]:
 

Thank you¶

MOhamed ElMesawy¶